home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Emulators / v2600 / Source.lha / Source / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  15.9 KB  |  880 lines

  1. /*****************************************************************************
  2.  
  3.    This file is part of x2600, the Atari 2600 Emulator
  4.    ===================================================
  5.    
  6.    Copyright 1996 Alex Hornby. For contributions see the file CREDITS.
  7.  
  8.    This software is distributed under the terms of the GNU General Public
  9.    License. This is free software with ABSOLUTELY NO WARRANTY.
  10.    
  11.    See the file COPYING for Details.
  12.    
  13.    Tweaked by Matthew Stroup for Amiga v2600, April 24, 1997.
  14.  
  15. ******************************************************************************/
  16.  
  17. /* 
  18.  * Holds the memory access routines to both memory and memory mapped
  19.  * i/o, hence memory.c
  20.  *
  21.  * Uses GNU C extensions.
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include "types.h"
  27. #include "address.h"
  28. #include "vmachine.h"
  29. #include "misc.h"
  30. #include "display.h"
  31. #include "raster.h"
  32. #include "collision.h"
  33. #include "col_mask.h"
  34. #include "options.h"
  35. #include "keyboard.h"
  36. #include "sound.h"
  37.  
  38. extern CLOCK clkcount;
  39. extern CLOCK clk;
  40. extern int beamadj;
  41.  
  42. /* Undecoded Read, for executable code etc. */
  43. /* a: address to read */
  44. /* returns: byte at address a */
  45. UBYTE undecRead (ADDRESS a)
  46. {
  47.   if (a & 0x1000)
  48.     return theRom[a & 0xfff];
  49.   else
  50.     return theRam[a & 0x7f];
  51. }
  52.  
  53.  
  54. __inline void bank_switch_write (ADDRESS a, UBYTE b)
  55. {
  56.   a&=0xfff;
  57.   switch (base_opts.bank)
  58.     {
  59.  
  60.     case 1:
  61.       /* Atari 8k F8 */
  62.       switch (a)
  63.     {
  64.     case 0xff8:
  65.       theRom = &theCart[0];
  66.       break;
  67.     case 0xff9:
  68.       theRom = &theCart[4096];
  69.       break;
  70.     }
  71.       break;
  72.  
  73.     case 2:
  74.       /* Atari 16k F6 */
  75.       switch (a)
  76.     {
  77.     case 0xff6:
  78.       theRom = &theCart[0];
  79.       break;
  80.     case 0xff7:
  81.       theRom = &theCart[4096];
  82.       break;
  83.     case 0xff8:
  84.       theRom = &theCart[8192];
  85.       break;
  86.     case 0xff9:
  87.       theRom = &theCart[12288];
  88.       break;
  89.     }
  90.       break;
  91.  
  92.     case 3:
  93.       /* Parker Brothers 8k E0 */
  94.       {
  95.     ADDRESS a1;
  96.     if (a > 0xfdf && a < 0xfe8) 
  97.       {
  98.         a1=(a&0x07)<<10;
  99.         memcpy(&cartScratch[0],&theCart[a1],0x400);
  100.       }
  101.     else if (a > 0xfe7 && a < 0xff0) 
  102.       {
  103.         a1=(a&0x07)<<10;
  104.         memcpy(&cartScratch[0x400],&theCart[a1],0x400);
  105.       } 
  106.     else if (a > 0xfef && a < 0xff8) 
  107.       {
  108.         a1=(a&0x07)<<10;
  109.         memcpy(&cartScratch[0x800],&theCart[a1],0x400);
  110.       }
  111.       }
  112.       break;
  113.  
  114.     case 4:
  115.       /* CBS Ram Plus FA */
  116.       if (a < 0x100) 
  117.     cartRam[a & 0xff]=b;
  118.       else
  119.     {      
  120.       switch (a)
  121.         {
  122.         case 0xff8:
  123.           theRom = &theCart[0];
  124.           break;
  125.         case 0xff9:
  126.           theRom = &theCart[4096];
  127.           break;
  128.         case 0xffa:
  129.           theRom = &theCart[8192];
  130.           break;
  131.         }
  132.     }
  133.       break;
  134.  
  135.     case 5:
  136.       /* Atari 16k + super chip ram F6SC */
  137.       if (a < 0x80) 
  138.     cartRam[a & 0x7f] = b;
  139.       else
  140.     {
  141.       switch (a)
  142.         {
  143.         case 0xff6:
  144.           theRom = &theCart[0];
  145.           break;
  146.         case 0xff7:
  147.           theRom = &theCart[4096];
  148.           break;
  149.         case 0xff8:
  150.           theRom = &theCart[8192];
  151.           break;
  152.         case 0xff9:
  153.           theRom = &theCart[12288];
  154.           break;
  155.         }
  156.     }
  157.       break;
  158.     }
  159. }
  160.  
  161. __inline UBYTE bank_switch_read (ADDRESS a)
  162. {
  163.   UBYTE res;
  164.  
  165.   a&=0xfff;
  166.   switch (base_opts.bank)
  167.     {
  168.     case 1:
  169.       /* Atari 8k F8 */
  170.       switch (a)
  171.     {
  172.     case 0xff8:
  173.       theRom = &theCart[0];
  174.       break;
  175.     case 0xff9:
  176.       theRom = &theCart[4096];
  177.       break;
  178.     }
  179.       res=theRom[a];
  180.       break;
  181.  
  182.     case 2:
  183.       /* Atari 16k F6 */
  184.       switch (a)
  185.     {
  186.     case 0xff6:
  187.       theRom = &theCart[0];
  188.       break;
  189.     case 0xff7:
  190.       theRom = &theCart[4096];
  191.       break;
  192.     case 0xff8:
  193.       theRom = &theCart[8192];
  194.       break;
  195.     case 0xff9:
  196.       theRom = &theCart[12288];
  197.       break;
  198.     }
  199.       res=theRom[a];
  200.       break;
  201.  
  202.     case 3:
  203.       /* Parker Brothers 8k E0 */
  204.       /* Parker Brothers 8k E0 */
  205.       {
  206.     ADDRESS a1;
  207.     if (a > 0xfdf && a < 0xfe8) 
  208.       {
  209.         a1=(a&0x07)<<10;
  210.         memcpy(&cartScratch[0],&theCart[a1],0x400);
  211.       }
  212.     else if (a > 0xfe7 && a < 0xff0) 
  213.       {
  214.         a1=(a&0x07)<<10;
  215.         memcpy(&cartScratch[0x400],&theCart[a1],0x400);
  216.       } 
  217.     else if (a > 0xfef && a < 0xff8) 
  218.       {
  219.         a1=(a&0x07)<<10;
  220.         memcpy(&cartScratch[0x800],&theCart[a1],0x400);
  221.       }
  222.       }
  223.       res=theRom[a];
  224.       break;
  225.  
  226.     case 4:
  227.       /* CBS Ram Plus FA */
  228.       if (a > 0xff && a < 0x200) 
  229.       res=cartRam[a & 0xff];
  230.       else
  231.     {      
  232.       switch (a)
  233.         {
  234.         case 0xff8:
  235.           theRom = &theCart[0];
  236.           break;
  237.         case 0xff9:
  238.           theRom = &theCart[4096];
  239.           break;
  240.         case 0xffa:
  241.           theRom = &theCart[8192];
  242.           break;
  243.         }
  244.       res=theRom[a];
  245.     }
  246.       break;
  247.  
  248.     case 5:
  249.       /* Atari 16k + super chip ram F6SC */
  250.       if (a > 0x7f && a < 0x100) 
  251.     res=cartRam[a & 0x7f];
  252.       else
  253.     {
  254.       switch (a)
  255.         {
  256.         case 0xff6:
  257.           theRom = &theCart[0];
  258.           break;
  259.         case 0xff7:
  260.           theRom = &theCart[4096];
  261.           break;
  262.         case 0xff8:
  263.           theRom = &theCart[8192];
  264.           break;
  265.         case 0xff9:
  266.           theRom = &theCart[12288];
  267.           break;
  268.         }
  269.       res=theRom[a];
  270.     }
  271.       break;
  272.     }
  273.   return res;
  274. }
  275.  
  276.  
  277. /* Decoded write to memory */
  278. /* a: address written to */
  279. /* b: byte value written */
  280. void decWrite (ADDRESS a, UBYTE b)
  281. {
  282.   int i;
  283.  
  284.   /* A Write to the ROM area */
  285.   if (a & 0x1000)
  286.     {
  287.       bank_switch_write (a,b);
  288.     }
  289.   /* A Write to the RAM area in Page 0 and 1 */
  290.   else if ((a & 0x280) == 0x80)
  291.     {
  292.       theRam[a & 0x7f] = b;
  293.     }
  294.   /* TIA */
  295.   else if (!(a & 0x80))
  296.     {
  297.       switch (a & 0x7f)
  298.     {
  299.     case VSYNC:
  300.       if (b & 0x02)
  301.         {
  302.           /* Start vertical sync */
  303.           vbeam_state = VSYNCSTATE;
  304.         }
  305.       break;
  306.     case VBLANK:
  307.       do_vblank (b);
  308.       /* Ground paddle pots */
  309.       if (b & 0x80)
  310.         {
  311.           /* Grounded ports */
  312.           tiaRead[INPT0] = 0x00;
  313.           tiaRead[INPT1] = 0x00;
  314.         }
  315.       else
  316.         {
  317.           /* Processor now measures time for a logic 1 to appear
  318.              at each paddle port */
  319.           tiaRead[INPT0] = 0x80;
  320.           tiaRead[INPT1] = 0x80;
  321.           paddle[0].val = clk;
  322.           paddle[1].val = clk;
  323.         }
  324.       /* Logic for dumped input ports */
  325.       if (b & 0x40)
  326.         {
  327.           if (tiaWrite[VBLANK] & 0x40)
  328.         {
  329.           tiaRead[INPT4] = 0x80;
  330.           tiaRead[INPT5] = 0x80;
  331.         }
  332.           else
  333.         {
  334.           read_trigger ();
  335.         }
  336.         }
  337.       tiaWrite[VBLANK] = b;
  338.       break;
  339.     case WSYNC:
  340.       /* Skip to HSYNC pulse */
  341.       do_hsync ();
  342.       break;
  343.     case RSYNC:
  344.       /* used in chip testing */
  345. //      printf ("ARGHH an undocumented RSYNC!\n");
  346.       break;
  347.     case NUSIZ0:
  348.       /*
  349.          printf("P0 nusize: ebeamx=%d, ebeamy=%d, nusize=%02x\n",
  350.          ebeamx, ebeamy, (int)b);
  351.        */
  352.       pl[0].nusize = b & 0x07;
  353.       ml[0].width = (b & 0x30) >> 4;
  354.       break;
  355.     case NUSIZ1:
  356.       /*
  357.          printf("P1 nusize: ebeamx=%d, ebeamy=%d, nusize=%02x\n",
  358.          ebeamx, ebeamy, (int)b);
  359.        */
  360.       pl[1].nusize = b & 0x07;
  361.       ml[1].width = (b & 0x30) >> 4;
  362.       break;
  363.     case COLUP0:
  364.       do_unified_change (0, tv_color (b));
  365.       break;
  366.     case COLUP1:
  367.       do_unified_change (1, tv_color (b));
  368.       break;
  369.     case COLUPF:
  370.       do_unified_change (2, tv_color (b));
  371.       break;
  372.     case COLUBK:
  373.       /*printf("BKcolour = %d, line=%d\n", (int)(b>>1), ebeamy); */
  374.       do_unified_change (3, tv_color (b));
  375.       break;
  376.     case CTRLPF:
  377.       tiaWrite[CTRLPF] = b & 0x37;    /* Bitmask 00110111 */
  378.       do_pfraster_change (0, 3, b & 0x01);    /* Reflection */
  379.       
  380.       /* Normal/Alternate priority */
  381.       do_unified_change(4, (b & 0x04));
  382.       
  383.       /* Scores/Not scores */
  384.       do_unified_change(5, (b & 0x02));
  385.  
  386.       break;
  387.     case REFP0:
  388.       pl[0].reflect = (b & 0x08) >> 3;
  389.       break;
  390.     case REFP1:
  391.       pl[1].reflect = (b & 0x08) >> 3;
  392.       break;
  393.     case PF0:
  394.       do_pfraster_change (0, 0, b & 0xf0);
  395.       break;
  396.     case PF1:
  397.       do_pfraster_change (0, 1, b);
  398.       break;
  399.     case PF2:
  400.       do_pfraster_change (0, 2, b);
  401.       break;
  402.     case RESP0:
  403.       /* Ghost in pacman!
  404.          if(beamadj == 0) {
  405.          printf("RESP0: ebeamx=%d, ebeamy=%d\n",
  406.          ebeamx, ebeamy); 
  407.          show();
  408.          } */
  409.       pl[0].x = ebeamx + beamadj;
  410.       /* As per page 20 Stella Programmers Guide */
  411.       if (pl[0].x < 0)
  412.         pl[0].x = 0;
  413.       break;
  414.     case RESP1:
  415.       /*if(beamadj == 0) {
  416.          printf("RESP1: ebeamx=%d, ebeamy=%d\n",
  417.          ebeamx, ebeamy);
  418.          show(); 
  419.          } */
  420.       pl[1].x = ebeamx + beamadj;
  421.       /* As per page 20 Stella Programmers Guide */
  422.       if (pl[1].x < 0)
  423.         pl[1].x = 0;
  424.       break;
  425.     case RESM0:
  426.       ml[0].x = ebeamx + beamadj;
  427.       /* As per page 20 Stella Programmers Guide */
  428.       if (ml[0].x < 0)
  429.         ml[0].x = 0;
  430.       break;
  431.     case RESM1:
  432.       ml[1].x = ebeamx + beamadj;
  433.       /* As per page 20 Stella Programmers Guide */
  434.       if (ml[1].x < 0)
  435.         ml[1].x = 0;
  436.       break;
  437.     case RESBL:
  438.       ml[2].x = ebeamx + beamadj;
  439.       /* As per page 20 Stella Programmers Guide */
  440.       if (ml[2].x < 0)
  441.         ml[2].x = 0;
  442.       break;
  443.     case AUDC0:
  444.       sound_waveform (0, b & 0x0f);
  445.       break;
  446.     case AUDC1:
  447.       sound_waveform (1, b & 0x0f);
  448.       break;
  449.     case AUDF0:
  450.       sound_freq (0, b & 0x1f);
  451.       break;
  452.     case AUDF1:
  453.       sound_freq (1, b & 0x1f);
  454.       break;
  455.     case AUDV0:
  456.       sound_volume (0, b & 0x0f);
  457.       break;
  458.     case AUDV1:
  459.       sound_volume (1, b & 0x0f);
  460.       break;
  461.     case GRP0:
  462.       do_plraster_change (0, 0, b);
  463.       do_plraster_change (1, 1, b);
  464.       break;
  465.     case GRP1:
  466.       do_plraster_change (1, 0, b);
  467.       do_plraster_change (0, 1, b);
  468.       ml[2].vdel = ml[2].enabled;
  469.       break;
  470.     case ENAM0:
  471.       ml[0].enabled = b & 0x02;
  472.       if (tiaWrite[RESMP0])
  473.         ml[0].enabled = 0;
  474.       break;
  475.     case ENAM1:
  476.       ml[1].enabled = b & 0x02;
  477.       if (tiaWrite[RESMP1])
  478.         ml[1].enabled = 0;
  479.       break;
  480.     case ENABL:
  481.       ml[2].enabled = b & 0x02;
  482.       break;
  483.     case HMP0:
  484.       pl[0].hmm = (b >> 4);
  485.       break;
  486.     case HMP1:
  487.       pl[1].hmm = (b >> 4);
  488.       break;
  489.     case HMM0:
  490.       ml[0].hmm = (b >> 4);
  491.       break;
  492.     case HMM1:
  493.       ml[1].hmm = (b >> 4);
  494.       break;
  495.     case HMBL:
  496.       ml[2].hmm = (b >> 4);
  497.       break;
  498.     case VDELP0:
  499.       pl[0].vdel_flag = b & 0x01;
  500.       break;
  501.     case VDELP1:
  502.       pl[1].vdel_flag = b & 0x01;
  503.       break;
  504.     case VDELBL:
  505.       ml[2].vdel_flag = b & 0x01;
  506.       break;
  507.     case RESMP0:
  508.       tiaWrite[RESMP0] = b & 0x02;
  509.       if (b & 0x02)
  510.         {
  511.           ml[0].x = pl[0].x + 4;
  512.           ml[0].enabled = 0;
  513.         }
  514.       break;
  515.     case RESMP1:
  516.       tiaWrite[RESMP1] = b & 0x02;
  517.       if (b & 0x02)
  518.         {
  519.           ml[1].x = pl[1].x + 4;
  520.           ml[1].enabled = 0;
  521.         }
  522.       break;
  523.     case HMOVE:
  524.       /* Player 0 */
  525.       if (pl[0].hmm & 0x08)
  526.         pl[0].x += ((pl[0].hmm ^ 0x0f) + 1);
  527.       else
  528.         pl[0].x -= pl[0].hmm;
  529.       if (pl[0].x > 160)
  530.         pl[0].x = -68;
  531.       else if (pl[0].x < -68)
  532.         pl[0].x = 160;
  533.  
  534.       /* Player 2 */
  535.       if (pl[1].hmm & 0x08)
  536.         pl[1].x += ((pl[1].hmm ^ 0x0f) + 1);
  537.       else
  538.         pl[1].x -= pl[1].hmm;
  539.       if (pl[1].x > 160)
  540.         pl[1].x = -68;
  541.       else if (pl[1].x < -68)
  542.         pl[1].x = 160;
  543.  
  544.       /* Missiles */
  545.       for (i = 0; i < 3; i++)
  546.         {
  547.           if (ml[i].hmm & 0x08)
  548.         ml[i].x += ((ml[i].hmm ^ 0x0f) + 1);
  549.           else
  550.         ml[i].x -= ml[i].hmm;
  551.           if (ml[i].x > 160)
  552.         ml[i].x = -68;
  553.           else if (ml[i].x < -68)
  554.         ml[i].x = 160;
  555.         }
  556.       break;
  557.     case HMCLR:
  558.       pl[0].hmm = 0;
  559.       pl[1].hmm = 0;
  560.       for (i = 0; i < 3; i++)
  561.         ml[i].hmm = 0;
  562.       break;
  563.     case CXCLR:
  564.       col_state=0;
  565.       break;
  566.     }
  567.     }
  568.   else
  569.     {
  570.       switch (a & 0x2ff)
  571.     {
  572.       /* RIOT I/O ports */
  573.     case SWCHA:
  574.       riotWrite[SWCHA] = b;
  575.       break;
  576.     case SWACNT:
  577.       riotWrite[SWACNT] = b;
  578.       break;
  579.     case SWCHB:
  580.     case SWBCNT:
  581.       /* Do nothing */
  582.       break;
  583.  
  584.       /* Timer ports */
  585.     case TIM1T:
  586.       set_timer (0, b, clkcount);
  587.       break;
  588.     case TIM8T:
  589.       set_timer (3, b, clkcount);
  590.       break;
  591.     case TIM64T:
  592.       set_timer (6, b, clkcount);
  593.       break;
  594.     case T1024T:
  595.       set_timer (10, b, clkcount);
  596.       break;
  597.     default:
  598.       printf ("Unknown write %x\n", a);
  599.       show ();
  600.       break;
  601.     }
  602.     }
  603. }
  604.  
  605.  
  606. /* Decoded read from memory */
  607. /* a: address to read */
  608. /* returns: byte value from address a */
  609. UBYTE decRead (ADDRESS a)
  610. {
  611.   UBYTE res = 65;
  612.  
  613.   if (a & 0x1000)
  614.     {
  615.       a = a & 0xfff;
  616.       if (base_opts.bank != 0)
  617.     res= bank_switch_read (a);
  618.       else
  619.     res = theRom[a];
  620.     }
  621.   else if ((a & 0x280) == 0x80)
  622.     {
  623.       res = theRam[a & 0x7f];
  624.     }
  625.   else if (!(a & 0x80))
  626.     {
  627.       switch (a & 0x0f)
  628.     {
  629.       /* TIA */
  630.     case CXM0P:
  631.       res = (col_state & CXM0P_MASK) << 6;
  632.       break;
  633.     case CXM1P:
  634.       res = (col_state & CXM1P_MASK) << 4;
  635.       break;
  636.     case CXP0FB:
  637.       res = (col_state & CXP0FB_MASK) << 2;
  638.       break;
  639.     case CXP1FB:
  640.       res = (col_state & CXP1FB_MASK);
  641.       break;
  642.     case CXM0FB:
  643.       res = (col_state & CXM0FB_MASK) >> 2;
  644.       break;
  645.     case CXM1FB:
  646.       res = (col_state & CXM1FB_MASK) >> 4;
  647.       break;
  648.     case CXBLPF:
  649.       res = (col_state & CXBLPF_MASK) >> 5;
  650.       break;
  651.     case CXPPMM:
  652.       res = (col_state & CXPPMM_MASK) >> 7;
  653.       break;
  654.     case INPT0:
  655.       if (base_opts.lcon == PADDLE)
  656.         {
  657.           tiaRead[INPT0] = do_paddle (0);
  658.         }
  659.       else if (base_opts.lcon == KEYPAD)
  660.         do_keypad (0, 0);
  661.       res = tiaRead[INPT0];
  662.       break;
  663.     case INPT1:
  664.       if (base_opts.lcon == PADDLE)
  665.         {
  666.           tiaRead[INPT1] = do_paddle (1);
  667.         }
  668.       if (base_opts.lcon == KEYPAD)
  669.         tiaRead[INPT1]=do_keypad (0, 1);
  670.       res = tiaRead[INPT1];
  671.       break;
  672.     case INPT2:
  673.       if (base_opts.rcon == KEYPAD)
  674.         do_keypad (1, 0);
  675.       res = tiaRead[INPT2];
  676.       break;
  677.     case INPT3:
  678.       if (base_opts.rcon == KEYPAD)
  679.          tiaRead[INPT3]=do_keypad ( 1, 1);
  680.       res = tiaRead[INPT3];
  681.       break;
  682.     case INPT4:
  683.       switch (base_opts.lcon)
  684.         {
  685.         case KEYPAD:
  686.           tiaRead[INPT4]=do_keypad ( 0, 2);
  687.           break;
  688.         case STICK:
  689.           read_trigger ();
  690.           break;
  691.         }
  692.       res =tiaRead[INPT4];
  693.       break;
  694.     case INPT5:
  695.       switch (base_opts.rcon)
  696.         {
  697.         case KEYPAD:
  698.           tiaRead[INPT5]=do_keypad (1, 2);
  699.           break;
  700.         case STICK:
  701.           read_trigger ();
  702.           break;
  703.         }
  704.       res = tiaRead[INPT5];
  705.       break;
  706.     case 0x0e:
  707.     case 0x0f:
  708.       res = 0x0f;
  709.       /* RAM, mapped to page 0 and 1 */
  710.     }
  711.     }
  712.   else
  713.     {
  714.       switch (a & 0x2ff)
  715.     {
  716.       /* Timer output */
  717.     case INTIM:
  718.     case 0x285:
  719.     case 0x286:
  720.     case TIM1T:
  721.     case TIM8T:
  722.     case TIM64T:
  723.     case T1024T:
  724.       res = do_timer (clkcount);
  725.       /*printf("Timer is %d res is %d\n", res, timer_res); */
  726.       break;
  727.     case SWCHA:
  728.       switch (base_opts.lcon)
  729.         {
  730.         case PADDLE:
  731.           if (base_opts.lcon == PADDLE)
  732.         {
  733.           if (mouse_button ())
  734.             riotRead[SWCHA] &= 0x7f;
  735.           else
  736.             riotRead[SWCHA] |= 0x80;
  737.         }
  738.           else if (base_opts.rcon == PADDLE)
  739.         {
  740.           if (mouse_button ())
  741.             riotRead[SWCHA] &= 0xbf;
  742.           else
  743.             riotRead[SWCHA] |= 0x40;
  744.         }
  745.           break;
  746.         case STICK:
  747.           read_stick ();
  748.           break;
  749.         }
  750.       res = riotRead[SWCHA];
  751.       break;
  752.       /* Switch B is hardwired to input */
  753.     case SWCHB:
  754.     case SWCHB + 0x100:
  755.       read_console ();
  756.       res = riotRead[SWCHB];
  757.       break;
  758.     default:
  759.       printf ("Unknown read 0x%x\n", a & 0x2ff);
  760.       show ();
  761.       res = 65;
  762.       break;
  763.     }
  764.     }
  765.   return res;
  766. }
  767.  
  768.  
  769. /* Debugging read from memory */
  770. /* a: address to read from */
  771. /* returns: value at address a, WITHOUT side effects */
  772. UBYTE dbgRead (ADDRESS a)
  773. {
  774.   UBYTE res;
  775.  
  776.   if (a & 0x1000)
  777.     {
  778.       a = a & 0xfff;
  779.       res = theRom[a];
  780.       if (base_opts.bank != 0)
  781.     bank_switch_read (a);
  782.     }
  783.   else if ((a & 0x280) == 0x80)
  784.     {
  785.       res = theRam[a & 0x7f];
  786.     }
  787.   else if (!(a & 0x80))
  788.     {
  789.       switch (a & 0x0f)
  790.     {
  791.       /* TIA */
  792.     case COLUP0:
  793.       res = colour_table[P0M0_COLOUR];
  794.       break;
  795.     case COLUP1:
  796.       res = colour_table[P1M1_COLOUR];
  797.       break;
  798.     case COLUPF:
  799.       res = colour_table[PFBL_COLOUR];
  800.       break;
  801.     case COLUBK:
  802.       res = colour_table[BK_COLOUR];
  803.       break;
  804.     case CTRLPF:
  805.       res = tiaWrite[CTRLPF];    /* Bitmask 00110111 */
  806.       break;
  807.     case REFP0:
  808.       res = tiaWrite[REFP0];
  809.       break;
  810.     case REFP1:
  811.       res = tiaWrite[REFP1];
  812.       break;
  813.     case PF0:
  814.       res = pf[0].pf0;
  815.       break;
  816.     case PF1:
  817.       res = pf[0].pf1;
  818.       break;
  819.     case PF2:
  820.       res = pf[0].pf2;
  821.       break;
  822.       /*  case CXM0P:
  823.          break;
  824.          case CXM1P:
  825.          break;
  826.          case CXP0FB:
  827.          break;  
  828.          case CXP1FB:
  829.          break;  
  830.          case CXM0FB:
  831.          break; 
  832.          case CXM1FB:
  833.          break; 
  834.          case CXBLPF:
  835.          break;  
  836.          case CXPPMM:
  837.          break;
  838.          case INPT0:
  839.          break;
  840.          case INPT1:
  841.          break;
  842.          case INPT2:
  843.          break;
  844.          case INPT3:
  845.          break;
  846.          case INPT4:
  847.          break;
  848.          case INPT5:
  849.          break;
  850.        */
  851.     }
  852.     }
  853.   else
  854.     {
  855.       switch (a & 0x2ff)
  856.     {
  857.       /* Timer output */
  858.     case INTIM:
  859.     case 0x285:
  860.     case 0x29d:
  861.     case INTIM + 0x100:
  862.       res = riotRead[INTIM];
  863.       break;
  864.     case SWCHA:
  865.     case SWCHA + 0x100:
  866.       res = riotRead[SWCHA];
  867.       break;
  868.       /* Switch B is hardwired to input */
  869.     case SWCHB:
  870.     case SWCHB + 0x100:
  871.       res = riotRead[SWCHB];
  872.       break;
  873.     default:
  874.       res = 0;
  875.       break;
  876.     }
  877.     }
  878.   return res;
  879. }
  880.